<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="biqe2" id="biqe2"><span data-lake-id="uf919032d" id="uf919032d">典型回答</span></h1>
  <p data-lake-id="uac789b98" id="uac789b98"><br></p>
  <p data-lake-id="uba7eae30" id="uba7eae30"><span data-lake-id="u72a66414" id="u72a66414">在 MySQL 中，可以使用</span><code data-lake-id="u81229797" id="u81229797"><span data-lake-id="u02e30d95" id="u02e30d95"> INSERT INTO ... ON DUPLICATE KEY UPDATE </span></code><span data-lake-id="uebaf55d9" id="uebaf55d9">语句实现 insertOrUpdate 功能。</span></p>
  <p data-lake-id="udd7c547a" id="udd7c547a"><span data-lake-id="uc9d0c602" id="uc9d0c602">​</span><br></p>
  <blockquote data-lake-id="uc392e45f" id="uc392e45f">
   <p data-lake-id="u45b3c2f3" id="u45b3c2f3"><span data-lake-id="u37ef0a77" id="u37ef0a77" class="lake-fontsize-12" style="color: rgb(33, 37, 41)">需要</span><strong><span data-lake-id="ud751d981" id="ud751d981" class="lake-fontsize-12" style="color: rgb(33, 37, 41)">注意</span></strong><span data-lake-id="u26e7b9b8" id="u26e7b9b8" class="lake-fontsize-12" style="color: rgb(33, 37, 41)">：在on duplicate key时，会在前一个索引值到当前值加临键锁，极容易造成死锁。</span></p>
  </blockquote>
  <p data-lake-id="ue8944e29" id="ue8944e29"><span data-lake-id="u681e9935" id="u681e9935">​</span><br></p>
  <p data-lake-id="u332cab6c" id="u332cab6c"><span data-lake-id="u10ef02e7" id="u10ef02e7">要使用</span><code data-lake-id="ueb36f65b" id="ueb36f65b"><span data-lake-id="uc324a1d9" id="uc324a1d9"> INSERT INTO ... ON DUPLICATE KEY UPDATE</span></code><span data-lake-id="u4b7ec34d" id="u4b7ec34d"> 语句，需要满足以下条件：</span></p>
  <ol list="u00b97e94">
   <li fid="ub458deb6" data-lake-id="uff9705b4" id="uff9705b4"><span data-lake-id="u2cf2909a" id="u2cf2909a">表必须有主键或唯一索引；</span></li>
   <li fid="ub458deb6" data-lake-id="u0ba3cc97" id="u0ba3cc97"><span data-lake-id="u966105b9" id="u966105b9">插入的数据必须包含主键或唯一索引列；</span></li>
   <li fid="ub458deb6" data-lake-id="uc7b4a7f8" id="uc7b4a7f8"><span data-lake-id="ubf684399" id="ubf684399">主键或唯一索引列的值不能为 NULL。</span></li>
  </ol>
  <p data-lake-id="u6bab15c8" id="u6bab15c8"><span data-lake-id="uff032b80" id="uff032b80">​</span><br></p>
  <p data-lake-id="u8ee920b3" id="u8ee920b3"><span data-lake-id="u9d074057" id="u9d074057">举个栗子：</span></p>
  <p data-lake-id="u8a7295a5" id="u8a7295a5"><span data-lake-id="u33f311db" id="u33f311db">​</span><br></p>
  <p data-lake-id="u47ff5ad6" id="u47ff5ad6"><span data-lake-id="ufbadf2f1" id="ufbadf2f1">假设有一个 student 表，包含 id、name 和 age 三列，其中 id 是主键。现在要插入一条数据，如果该数据的主键已经存在，则更新该数据的姓名和年龄，否则插入该数据。</span></p>
  <p data-lake-id="u65c33c36" id="u65c33c36"><span data-lake-id="u7ce6cf5e" id="u7ce6cf5e">​</span><br></p>
  <pre lang="java"><code>
INSERT INTO student (id, name, age) VALUES (1, 'Alice', 20)
ON DUPLICATE KEY UPDATE name='Alice', age=20;
</code></pre>
  <p data-lake-id="ud11cae7c" id="ud11cae7c"><br></p>
  <h1 data-lake-id="mwEwk" id="mwEwk"><span data-lake-id="uf825b431" id="uf825b431">扩展知识</span></h1>
  <p data-lake-id="u11ebcb66" id="u11ebcb66"><br></p>
  <h2 data-lake-id="gF5n3" id="gF5n3"><span data-lake-id="u7a61f316" id="u7a61f316">类似SQL</span></h2>
  <p data-lake-id="ued10a58c" id="ued10a58c"><br></p>
  <p data-lake-id="u5fba3306" id="u5fba3306"><span data-lake-id="u46fff34b" id="u46fff34b">除了INSERT INTO ... ON DUPLICATE KEY UPDATE，还有一些类似的 SQL 语句，比如：</span></p>
  <p data-lake-id="u54921f9c" id="u54921f9c"><span data-lake-id="ua708560e" id="ua708560e">​</span><br></p>
  <ol list="ubc6ac054">
   <li fid="ud3170f98" data-lake-id="u715be029" id="u715be029"><span data-lake-id="u0df0b8c6" id="u0df0b8c6">REPLACE INTO</span><span data-lake-id="u9aca055a" id="u9aca055a">: 如果存在唯一索引冲突，则先删除旧记录，再插入新记录。</span></li>
  </ol>
  <p data-lake-id="u50c50de3" id="u50c50de3"><br></p>
  <ol list="ubc6ac054" start="2">
   <li fid="ud3170f98" data-lake-id="u5b59bfa1" id="u5b59bfa1"><span data-lake-id="u2ee3f803" id="u2ee3f803">INSERT IGNORE INTO: 如果唯一索引冲突，则忽略该条插入操作，不报错。</span></li>
  </ol>
 </body>
</html>